import json
from redis.utils import pipeline
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from .models import GoodsCategory, SKU, GoodsVisitCount
from django.core.paginator import Paginator
from qingmei_mall.utils.response_code import RETCODE

from qingmei_mall.utils.get_category import get_category
from qingmei_mall.utils.breadcrumb import breadcrumd

from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from .models import GoodsCategory,SKU,GoodsVisitCount


from django import http



import json
from django.contrib.auth.mixins import LoginRequiredMixin
# 列表页
class ListView(View):
    def get(self, request, category_id, page_num):
        # 三级分类
        categories = get_category()
        # 面包屑
        # category_id是三级分类id
        try:
            cat3 = GoodsCategory.objects.get(id=category_id)
        except:
            return render(request, '404.html')

        breadcrumb = breadcrumd(cat3)

        # 商品数据(排序/分页)
        sort = request.GET.get("sort", "default")
        # 人气排序 根据sales 从大到小
        if sort == "hot":
            skus = SKU.objects.filter(is_launched=True, category_id=category_id).order_by("-sales")
        # 价格排序
        elif sort == "price":
            skus = SKU.objects.filter(is_launched=True, category_id=category_id).order_by("price")
        # 默认排序
        else:
            skus = SKU.objects.filter(is_launched=True, category_id=category_id).order_by("id")
        # 分页
        # 创建分页对象
        paginator = Paginator(skus, 5)
        # 获取当前页的数据
        page_skus = paginator.page(page_num)
        # 获取总页码
        total_page = paginator.num_pages
        # 热销排行

        context = {
            'categories': categories,  # 频道分类
            'breadcrumb': breadcrumb,  # 面包屑导航
            'sort': sort,  # 排序字段
            'category': cat3,  # 第三级分类
            'page_skus': page_skus,  # 分页后数据
            'total_page': total_page,  # 总页数
            'page_num': page_num,  # 当前页码
        }
        return render(request, "list.html", context)


# 热销排行
class HotView(View):
    def get(self, request, category_id):
        # 处理
        # 根据三级分类id：category_id查找该三级分类下的所有库存商品
        # hot_skus卖的最好的两款商品
        hot_skus = SKU.objects.filter(is_launched=True, category_id=category_id).order_by("-sales")[0:2]
        sku_list = []
        for sku in hot_skus:
            sku_list.append(
                {
                    "id": sku.id,
                    "default_image_url": sku.default_image.url,
                    "name": sku.name,
                    "price": sku.price
                }
            )
        # 响应
        data = {
            "code": RETCODE.OK,
            "errmsg": "OK",
            "hot_sku_list": sku_list
        }
        return http.JsonResponse(data)


# 详情页
class DetailView(View):
    def get(self, request, sku_id):
        # 商品频道分类
        categories = get_category()
        # 面包屑导航
        # 获取库存商品对象
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return render(request, '404.html')
        # 库存商品==>三级分类对象
        cat3 = sku.category
        breadcrumb = breadcrumd(cat3)
        # 库存商品信息
        # 查询规格
        # 查询该库存商品对应的规格选项表对象[<7>,<8>]  [8,11]
        # 构建库存商品选项数据与库存商品id的字典
        # skus_dict = {}
        # # 获取所有的库存商品对象
        # skus = SKU.objects.all()
        # for info in skus:
        #     # 获取该库存商品所对应的规格详情对象
        #     specs_list = info.specs.all()
        #     # 将每个库存商品的选项id加入到列表中
        #     spec_option_list = []  # [8,11]
        #     for spec in specs_list:
        #         spec_option_list.append(spec.option_id)
        #     skus_dict[tuple(spec_option_list)] = info.id  #
        skus_dict = {}
        skus = SKU.objects.all()
        for info in skus:
            specs_list = info.specs.all()
            spec_option_list = []
            for specc in specs_list:
                spec_option_list.append(specc.option_id)
            skus_dict[tuple(spec_option_list)]=info.id
        print(skus_dict)

        sku_option_list = sku.specs.order_by("spec_id")
        # [8,11]  8颜色规格  11内存
        option_id_list = [info.option_id for info in sku_option_list]
        spu = sku.spu
        specs = spu.specs.order_by("id")

        # 规格选项列表
        specs_list = []


        # 遍历所有的规格 并拿到该规格所对应的下标
        # 颜色==>0  内存==>1  [8,11]
        for index, spec in enumerate(specs):
            spec_dict = {
                # 规格名字
                "name": spec.name,
                # 所有选项列表
                "option_list": [],
            }
            # 遍历选项列表，得到每个选项对象
            # [8,9,10]
            for option in spec.options.all():
                # 复制当前库存商品的选项列表 [8,11] ==> [9,11]
                #  [9,11]  [10,11]  [8,12]
                # 根据该列表查找对应的库存商品
                option_id_list_temp = option_id_list[:]
                # 没有加select样式的选项[]
                option_id_list_temp[index] = option.id
                spec_dict["option_list"].append(
                    {
                        # 取每个选项的名字
                        "name": option.value,
                        # 判断该选项是否在该库存商品所对应的选项列表中，返回True或者False
                        "selected": option.id in option_id_list,
                        # 跳转库存商品的id
                        "sku_id": skus_dict.get(tuple(option_id_list_temp)),
                    }
                )
            specs_list.append(spec_dict)

        # 商品详情、商品评价、售后与包装
        # 热销排行

        context = {
            "categories": categories,
            "breadcrumb": breadcrumb,
            "sku": sku,
            "specs_list": specs_list
        }
        return render(request, "detail.html", context)


from datetime import datetime


class DetailVisitView(View):
    def post(self,request,category_id):
        # 验证
        if not all(category_id):
            return http.HttpResponseForbidden('三级分类id不能为空')
        try :
            cat3 = GoodsCategory.objects.get(id=category_id)

        except:
            return http.HttpResponseForbidden('三级分类无效')


        now_time=datetime.now()
        now_date='%d-%02d-%02d'%(now_time.year,now_time.month,now_time.day)
        try:
           counts= GoodsVisitCount.objects.get(category_id=cat3.id,date=now_date)
        except:
            #新增访问量
            GoodsVisitCount.objects.create(category_id=cat3.id, count=1)

        else:
            counts.count+=1
            counts.save()

        #处理
        #响应
        return http.JsonResponse({
            'code':RETCODE.OK,
            'errmsg':'OK'
        })




class HistoryView(View,LoginRequiredMixin):
    def post(self,request):
        #接受
        sku_id=json.loads(request.body.decode()).get('sku_id')
        #验证
        if not all([sku_id]):
            return http.HttpResponseForbidden('三级分类商品为输入')

        try :
            sku=SKU.objects.get(id=sku_id)
        except:
            return http.HttpResponseForbidden('商品不存在')

        #处理：redis存储

        user=request.user.id
        redis_cli=get_redis_connection('history')
        redis_pipeline = redis_cli.pipeline()
        keys = "history" + str(user)
        # 给redis列表去重
        redis_pipeline.lrem(keys, 0, sku_id)
        # 添加sku_id
        redis_pipeline.lpush(keys, sku_id)
        # 截取，保证redis中只有五条数据
        redis_pipeline.ltrim(keys, 0, 4)
        redis_pipeline.execute()
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': 'OK'
        })

    # 查询浏览记录
    def get(self, request):
        # 处理
        # 从redis中查询浏览记录
        redis_cli = get_redis_connection("history")
        user_id = request.user.id
        key = "history" + str(user_id)
        # 浏览记录列表 [1,2,3,4,5]
        sku_id_list = redis_cli.lrange(key, 0, -1)

        skus_list = []
        for sku_id in sku_id_list:
            sku = SKU.objects.get(id=sku_id)
            skus_list.append({
                "id": sku.id,
                "name": sku.name,
                "default_image_url": sku.default_image.url,
                "price": sku.price,
                "sku_url": "/detail/" + str(sku.id) + "/"
            })
        # 响应
        """
        {
            "code":"0",
            "errmsg":"OK",
            "skus":[
                {
                    "id":6,
                    "name":"Apple iPhone 8 Plus (A1864) 256GB 深空灰色 移动联通电信4G手机",
                    "default_image_url":"http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRbI2ARekNAAFZsBqChgk3141998",
                    "price":"7988.00"
                },
                {},
                {},

                ]
                }

        """
        return http.JsonResponse({
            "code": RETCODE.OK,
            "errmsg": "OK",
            "skus": skus_list
        })